#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "hash_object.h"
#include "hash_list.h"
#include "new.h"


static Pointer hash_list_create(Pointer _self, va_list* app)
{
    struct HashList *self = ((const struct Class *)HashObject)->ctor(_self, app);
	self->next=NULL;
	return self;
}

Pointer hash_list_remove_all(Pointer _list, char* key)
{
	struct HashList* list = _list;
	struct HashList* curlist;
	struct HashList* buflist;
	curlist=list;
	while(!strcmp((&(curlist->_))->key, key))
	{
		curlist = curlist->next;
		hash_list_delete_one(list);
		list=curlist;
		if(list==NULL)
		{
			return list;
		}
	}
	while(curlist->next)
	{
		while(!strcmp((&(curlist->_))->key, key))
		{
			curlist = curlist->next;
			hash_list_delete_one(list);
			list=curlist;
			if(list==NULL)
			{
				return list;
			}
		}
		if(curlist->next==NULL)
		{
			return list;	
		}
		if(!strcmp(((&(curlist->next)->_))->key, key))
		{
			buflist = curlist->next;
			curlist->next = curlist->next->next;
			hash_list_delete_one(buflist);
		}
		if(curlist->next==NULL)
		{
			return list;
		}
		curlist = curlist->next;
	}
	return list;
}

Pointer hash_list_prepend(Pointer _list, char* key, Pointer data, size_t datasize, unsigned int hash)
{
	struct HashList* list = _list;
	struct HashList* newlist;
    newlist = new(HashList, hash, datasize, data, key);
    newlist->next = list;
    return newlist;
}

Pointer hash_list_foreach(Pointer _list, void (*f)(char *key, Pointer data))
{
	struct HashList* list = _list;
	struct HashList* start_list;
	start_list = list;
	while(list!=NULL)
	{
		f((&(list->_))->key, (&(list->_))->data);
		list = list->next;
	}
	return start_list;
}

int hash_list_has(Pointer _list, char* key)
{
	struct HashList* list = _list;
	while(list!=NULL)
	{
		if(strcmp((&(list->_))->key, key)==0)
		{
			return 1;
		}
		list = list->next;
	}
	return 0;
}

void hash_list_delete_one(Pointer _self)
{
	struct HashList* self = _self;
	self = ((const struct Class *)HashObject)->dtor(&(self->_));
	free(self);
}

Pointer hash_list_delete(Pointer _self)
{
	struct HashList* self = _self;
	struct HashList* buf;
	while(self != NULL)
	{
		self = ((const struct Class *)HashObject)->dtor(&(self->_));
		buf = self;
		self = self->next;
		free(buf);
	}
	return self;
}


static const struct Class _HashList = {
    sizeof(struct HashList),
    hash_list_create,
    hash_list_delete
};

const void *HashList = &_HashList;